/**
 * Panel that contains textfields to search for an address at
 * the geocoding component or get a route.
 * The result will directly be displayed in the map of the application.
 * 
 * @author Kim Pommert
 * @version %I%, %G%
 */
qx.Class.define("qooxdoosample.cocktail.ui.AddressPanel",{
	
	extend: qx.ui.container.Composite,
	
	/**
	 * Class constructor.
	 * Instantiates an object of that class and configures the layout of the panel.
	 */
	construct: function()
	{
		this.base(arguments);
		
		// Create a layout for the container
		var layout = new qx.ui.layout.Grid(7, 2);
		layout.setColumnWidth(0, 75);
		layout.setColumnWidth(1, 160);
		
		this.setLayout(layout);
		
		this.initGeocoderPanel();
		this.initRoutePlannerPanel();
		
		this.initButtonListeners();
	},
	
	properties :
	{
		/**
		 * The geocoder that is used to convert the address to geographic coordinates.
		 */
    	geocoder :
    	{
      		nullable : true,
      		init : null,
      		check: "qooxdoosample.cocktail.maps.IGeoCoder"
      	},
      	
      	/**
      	 * The map where the location or route will be displayed.
      	 */
      	map:
      	{
      		nullable: true,
      		init: null,
      		check: "qooxdoosample.cocktail.maps.IMap"
      	},
      	
      	/**
      	 * The route planner that provides the route to the selected address.
      	 */
      	routePlanner:
      	{
      		nullable: true,
      		init: null,
      		check: "qooxdoosample.cocktail.maps.IRoutePlanner"
      	},
      	
      	/**
      	 * Textfield that is used for data input of the geocoder.
      	 * The input of this field will be the location that is displayed
      	 * in the map.
      	 */
      	tfGeocoderLocation:
      	{
      		nullable: true,
      		init: null,
      		check: "qx.ui.form.TextField"
      	},
      	
      	/**
      	 * Textfield that is used for data input of the route planner.
      	 * The input of this field will be the start point of the
      	 * route that is displayed in the map.
      	 */
      	tfRouteStart:
      	{
      		nullable: true,
      		init: null,
      		check: "qx.ui.form.TextField"
      	},
      	
      	/**
      	 * Textfield that is used for data input of the route planner.
      	 * The input of this field will be the target point of the
      	 * route that is displayed in the map.
      	 */
      	tfRouteEnd:
      	{
      		nullable: true,
      		init: null,
      		check: "qx.ui.form.TextField"
      	},      	
      	
      	/**
      	 * Button that sends the data of tfGeocoderLocation to the 
      	 * geocoding service.
      	 */
      	geocoderButton:
      	{
      		nullable: true,
      		init: null,
      		check: "qx.ui.form.Button"
      	},
      	
      	/**
      	 * Button that starts the calculation of the route.
      	 */
      	routeButton:
      	{
      		nullable: true,
      		init: null,
      		check: "qx.ui.form.Button"
      	}
      	
      	
	},
	
	
	members: 
	{
		/**
		 * Initialize the components of the geocoding area of this panel.
		 */
		initGeocoderPanel: function()
		{
			// set label
			var geocoderLabel = new qx.ui.basic.Label("geocoding");
			geocoderLabel.setFont("bold");
			this.add(geocoderLabel, {row: 0, column : 0, colSpan: 2});

			// set textfield
      		this.setTfGeocoderLocation(new qx.ui.form.TextField());
      		this.add(new qx.ui.basic.Label("Address:"), {row: 1, column : 0});
      		this.add(this.getTfGeocoderLocation(), {row: 1, column : 1});

			// set button
			this.setGeocoderButton(new qx.ui.form.Button("Send"));
			this.add(this.getGeocoderButton(), {row: 2, column : 1});			
		},
		
		/**
		 * Initialize the components of the route planner area of this panel.
		 */
		initRoutePlannerPanel: function()
		{
			// set label
			var routePlannerLabel = new qx.ui.basic.Label("route planner");
			routePlannerLabel.setFont("bold");
			this.add(routePlannerLabel, {row: 3, column : 0, colSpan: 2});

			// set textfields
      		this.setTfRouteStart(new qx.ui.form.TextField());
      		this.add(new qx.ui.basic.Label("Start:"), {row: 4, column : 0});
      		this.add(this.getTfRouteStart(), {row: 4, column : 1});
      		
      		this.setTfRouteEnd(new qx.ui.form.TextField());
      		this.add(new qx.ui.basic.Label("End:"), {row: 5, column : 0});
      		this.add(this.getTfRouteEnd(), {row: 5, column : 1});

			// set button
			this.setRouteButton(new qx.ui.form.Button("Send"));
			this.add(this.getRouteButton(), {row: 6, column : 1});			
		},
		
		/**
		 * Initialize the event listeners of the geocoding and route button.
		 */
		initButtonListeners: function()
		{
			this.getGeocoderButton().addListener("execute", function() {
          		this.drawMarker(this.getMap(), this.getGeocoder(), this.getTfGeocoderLocation().getValue());
      		}, this);
      		
      		this.getRouteButton().addListener("execute", function(){
      			this.drawRoute(this.getMap(), this.getRoutePlanner(), this.getTfRouteStart().getValue(), this.getTfRouteEnd().getValue());
      		}, this);
		},
		
		/**
		 * Provider of a service is changed. Update the references of all
		 * service components and reinitialize the button listeners.
		 * 
		 * @param aMap			{qooxdoosample.cocktail.maps.IMap}
		 * 							The map service
		 * @param aGeocoder		{qooxdoosample.cocktail.maps.IGeoCoder}
		 * 							The geocoding service
		 * @param aRoute		{qooxdoosample.cocktail.maps.IRoutePlanner}
		 * 							The route service
		 */
		updateServices: function(aMap, aGeocoder, aRoute)
		{
			this.setMap(aMap);
			this.setGeocoder(aGeocoder);
			this.setRoutePlanner(aRoute);
			this.initButtonListeners();
		},
		
		


		/**
		 * The map will be centered to the location of the selected entry and a marker
		 * will be added to that position, providing additional information about the location.
		 * 
		 * @param aMap			{qooxdoosample.cocktail.maps.IMap}
		 * 							The map that is used to display the location
		 * @param aGeocoder		{qooxdoosample.cocktail.maps.IGeoCoder}
		 * 							The geocoding service, that provides the information 
		 * 							about the selected location
		 * @param selection		{String}
		 * 							The text of the selected entry of the list.
		 * 							This is an address representation of the location. 
		 */
		drawMarker: function(aMap, aGeocoder, selection)
		{
			
			aMap.clearOverlays();
			var routeTextBox = document.getElementById("route");
			routeTextBox.innerHTML = "";
			
			/*
        	 * Result will be a marker at the selected location
        	 */   		
        	aGeocoder.getLocationInfo(selection, function(res){
        		if(res == null){
        			alert("Address not found");
        		}else{
        			// valid address -> coordinates found
        			var coords = res.getCoordinates();
        			
        			// set new center of the map
        			aMap.setCenter(coords);
        			
        			// add a marker on the results position
        			var marker = new qooxdoosample.cocktail.util.overlays.Marker(coords);
        			
        			var info = "";
        			
        			if(res.getAddress() != null)
        				info += "<b>" + res.getAddress() + "</b><br>";
        				
        			if(res.getCountry() != null)
        				info += "<ul><li>Country: " + res.getCountry() + "</li>";
        			if(res.getAdministrativeArea() != null)
        				info += "<li>Administrative area: " + res.getAdministrativeArea() + "</li>";
        			if(res.getSubAdministrativeArea() != null)
        				info += "<li>Subadministrative area: " + res.getSubAdministrativeArea() + "</li>";
					if(res.getLocality() != null)
        				info += "<li>Locality: " + res.getLocality() + "</li>";
					if(res.getThoroughfare() != null)
        				info += "<li>Thoroughfare: " + res.getThoroughfare() + "</li>";
					if(res.getPostalCode() != null)
        				info += "<li>Postal code: " + res.getPostalCode() + "</li></ul>";
        			
        			
        			
        			marker.setInfoText(info);
        			aMap.addOverlay(marker);
        		}
        	});
		},
		
		/**
		 * Draws a route from start- to end-location on the map and shows
		 * a description in a separate panel.
		 * 
		 * @param aMap			{qooxdoosample.cocktail.maps.IMap}
		 * 							The map that is used to display the route
		 * @param aRoutePlanner	{qooxdoosample.cocktail.maps.IRoutePlanner}
		 * 							The route service, that calculates the route
		 * @param start			{String}
		 * 							Address of the start point of the route
		 * @param end			{String}
		 * 							Address of the end point of the route 
		 */
		drawRoute: function(aMap, aRoutePlanner, start, end)
		{
        	aMap.clearOverlays();
        	
        	aRoutePlanner.getRoute(start, end, function(res){

				// create markers for start and end position of the route
        		var startMarker = new qooxdoosample.cocktail.util.overlays.Marker(res.getStartLatLng());
        		startMarker.setInfoText("Start");
        		var endMarker = new qooxdoosample.cocktail.util.overlays.Marker(res.getEndLatLng());
        		endMarker.setInfoText("End");
        		
        		// set the center of the map to the startpoint
        		aMap.setCenter(res.getStartLatLng());
        		aMap.setZoomLevel(11);
        		
        		// add markers and polyline
        		aMap.addOverlay(res.getPolyline());
        		aMap.addOverlay(startMarker);
        		aMap.addOverlay(endMarker);
        		
        		// load route Text        		
        		var routeTextBox = document.getElementById("route");
        		var txt = "";
        		for(i = 0; i < res.getNumSteps(); i++){
        			step = res.getStep(i);
        			txt += step.getDescription() + "<br>";
        		}
        		
        		// add duration and distance
        		txt += "<br>Dauer: " + parseInt(res.getDuration()/60) + " min";
        		txt += "<br>Entfernung: " + (res.getDistance()/1000) + " km";
        		
        		routeTextBox.innerHTML = txt;
        	});
        	
		}
		
		
	}
});